MongoDB 副本集与分片

MongoDB 系统讲解第二篇:02 篇理论篇讲过集群的概念轮廓,这一篇落到机制——oplog、选举、读偏好与写关注,以及分片架构里最重要的"片键怎么选"。

副本集:三种角色

Primary(主)   —— 所有写请求的入口
Secondary(从) —— 复制主的数据,可分担读;主挂了参与竞选
Arbiter(仲裁) —— 只有投票权没有数据,省资源凑奇数票(书里评价:能用真从库就别用仲裁者)

oplog 是复制的核心:主库的每个写操作记进一个固定大小的环形集合(local.oplog.rs),从库拉取并幂等地重放。固定大小意味着写太猛会把旧 oplog 冲掉——从库同步不上来就退回全量初始同步,生产要监控 oplog 窗口。

选举:主不可达时,有投票权的成员选出新主(类 Raft)。要点:

  • 投票成员数奇数(3 / 5 / 7)
  • priority 高的从库优先当选(可指定某台机器当主)
  • 大多数派存活才选得出主——两台机器坏一台和坏一半不一样,这就是为什么副本集最少 3 个数据节点

读写关注:一致性旋钮

readPreference(读走哪个节点)

模式 读谁 场景
primary(默认) 只读主 强一致读
primaryPreferred 主优先,主挂读从 高可用兜底
secondary 只读从 分析类查询,容忍旧数据
secondaryPreferred 从优先 读写分离典型选择
nearest 最近的 多地域部署

writeConcern(写确认级别):w: 1 主确认就返回(快,可能丢);w: "majority" 多数派确认(安全,慢一点);配 j: true 再加日志落盘确认。读级别和写级别的组合就是一致性与延迟的旋钮——这是副本集篇最核心的一句话。

分片架构:三个角色

mongos(路由)  —— 应用连它,按片键把请求路由到对应分片
config server  —— 存元数据:哪些数据在哪个分片(路由表)
shard          —— 每个分片本身就是一个副本集(高可用是分片的前提)

片键:分片里最重要的决定

片键(shard key)决定数据怎么分布,选了之后改起来要重建集合(除非在线 refine,且限制很多):

片键类型 分布 优点 缺点
范围片键(如 userId 区间) 相邻数据同分片 范围查询高效 单调递增键(时间戳)全写进最后一片=热点
哈希片键 均匀打散 写入均匀 范围查询变广播
复合片键 组合 兼顾 设计复杂

片键三条红线(书里反复强调):

  1. 基数要高(低基数字段,比如"性别",分不出几片)
  2. 别用单调递增的值做范围片键(追加写入全打到最后一片)
  3. 查询要带上片键(不带片键的查询变成"扇出到所有分片"的散射查询)

chunk 与均衡:数据按片键切成 chunk(块),balancer 后台在各分片间搬 chunk 保持均衡;搬不动的超大块叫 jumbo chunk(片键选择不当的产物)。

💡 我的记忆锚点:副本集解决"高可用 + 读扩展",分片解决"写与数据量"——先副本集,真到瓶颈再分片;分片的第一道坎不是运维,是片键设计。MongoDB 8.0 前后版本的分片机制一直在演进(config server 主从等),动手前查当时官方文档。


⬅️ 04-MongoDB 索引与查询优化 🏠 00-数据库 ➡️ 06-MongoDB 数据建模与实战模式